package com.scy.hospitalmanager.service.impl;

import com.scy.hospitalmanager.dao.mytest.TestDao;
import com.scy.hospitalmanager.pojo.ExtendedFieldDO;
import com.scy.hospitalmanager.pojo.ServMattInstCDO;
import com.scy.hospitalmanager.service.ServMattInstService;
import com.scy.hospitalmanager.until.ValidateUtil;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author Jin_zuo_wei
 * @ClassName ServMattInstServiceImpl
 * @Date 2021-09-26-16:36
 * @PackageName com.scy.hospitalmanager.service.impl
 * @Description
 * @Version 1.0.0
 */
@Component
public class ServMattInstServiceImpl implements ServMattInstService {
    @Resource
    TestDao servMattInstCDAO;

    /**
     * 查询服务事项实例列表
     */
    //标识定时任务。
    @XxlJob("uploadServInfoJobHandler")
    @Override
    public void queryServMattInstCDOList() {
        XxlJobHelper.log("Start:>>>----------开始获取服务事项列表----------<<<" + LocalDateTime.now());
        //获取当前时间。>>>
        LocalDateTime nowDate = LocalDateTime.now();
        //获取10分钟之前的时间。
        LocalDateTime beforeDate = nowDate.minusMinutes(20000);
        ServMattInstCDO servMattInstCDO = new ServMattInstCDO();
        try {
            //类型转换。
            Date endDate = Date.from(nowDate.atZone(ZoneId.systemDefault()).toInstant());
            Date startDate = Date.from(beforeDate.atZone(ZoneId.systemDefault()).toInstant());
            servMattInstCDO.setServMattBegntime(startDate);
            servMattInstCDO.setServMattEndtime(endDate);
            //通过结束时间，查询已完成的服务信息。
            List<ServMattInstCDO> servMattInstCDOS = servMattInstCDAO.queryServMattInstCDOList();
            if (servMattInstCDOS.isEmpty()) {
                XxlJobHelper.log("Warning:>>>----------服务事项列表为空----------<<<" + LocalDateTime.now());
            }
            XxlJobHelper.log("End:>>>----------服务事项列表获取成功----------<<<" + LocalDateTime.now());
            //定义外层Json对象。
            JSONObject outJsonObj = new JSONObject();
            //定义Json数组。
            JSONArray jsonArray = new JSONArray();
            XxlJobHelper.log("Start:>>>----------开始组装JsonArray----------<<<" + LocalDateTime.now());
            for (ServMattInstCDO ser : servMattInstCDOS) {
//                jsonArray.add(this.createMap(ser));
                this.sendPostRequest(this.createMap(ser));
            }
            //组装成Json对象数组。
//            outJsonObj.put("data", jsonArray);
            XxlJobHelper.log("End:>>>----------完成JsonArray组装----------<<<" + LocalDateTime.now());
            //发送请求。

        } catch (Exception e) {
            e.printStackTrace();
            XxlJobHelper.handleFail();
        }
        //任务结果默认为成功，可以通过XxlJobHelper.handleSuccess/handleFail()设置成功/失败。
    }

    /**
     * 组装Json。
     *
     * @param ser
     */
    private JSONObject createMap(ServMattInstCDO ser) {
        //定义JsonObj
        JSONObject servMattInstCDOObj = new JSONObject();
        //获取扩展字段信息。
        ExtendedFieldDO exField = servMattInstCDAO.queryExFieldByInstId(ser);
        XxlJobHelper.log(ser.toString());
        if (ValidateUtil.isEmpty(exField)) {
            XxlJobHelper.log("实例ID: "+ser.getServMattInstId()+"获取数据错误:>>>----------获取扩展字段获取为空----------<<<" + LocalDateTime.now());
        }
        //办理状态 登记/办结->0/1。办结时间不为null为办结。
        if (ValidateUtil.isEmpty(ser.getServMattEndtime())) {
            servMattInstCDOObj.put("affairStatus", "0");
            servMattInstCDOObj.put("affairDoneTime",null);
        } else {
            servMattInstCDOObj.put("affairStatus", "1");
        }
        //事件来源，外网UserId = null/空,为线下办理。
        //TODO 税务代办暂时不做。没有税务代办标识，可能会把税务代办归为线下办理或其他类型。
        if (StringUtils.isBlank(exField.getUserId())) {
            servMattInstCDOObj.put("workFrom", "线下办理");
        } else {
            //根据渠道标识匹配字段。
            servMattInstCDOObj.put("workFrom", this.matchChnlFlag(exField.getChnlFlag()));
        }
        //事件编号和办件编号，都通过调用方法进行赋值。
        this.matchServMattNo(ser.getServMattName(), ser.getServMattInstId(), servMattInstCDOObj);
        //事项名称
        servMattInstCDOObj.put("affairName", ser.getServMattName());
        //事项受理时间,办结时间。先判断登记避免空指针
        if ("0".equals(servMattInstCDOObj.get("affairStatus"))) {
            //登记
            //受理时间
            servMattInstCDOObj.put("affairApplyTime", ser.getServMattBegntime());
            //窗口工作人员工号
            // TODO 工号数据对不上待后期同步。自动任务插入000000，如何判断自动任务。
            servMattInstCDOObj.put("hallworkerNo", ser.getOpterId());
        } else if ("1".equals(servMattInstCDOObj.get("affairStatus"))) {
            //办结时间
            servMattInstCDOObj.put("affairDoneTime", ser.getServMattEndtime());
            if (ser.getServMattBegntime().compareTo(ser.getServMattEndtime()) == 0) {
                //一次办结
                servMattInstCDOObj.put("affairApplyTime", ser.getServMattBegntime());
            }
        }

        //登记或一次办结
        if ("0".equals(servMattInstCDOObj.get("affairStatus"))
                || ser.getServMattBegntime().compareTo(ser.getServMattEndtime()) == 0) {
            servMattInstCDOObj.put("affairApplyTime", ser.getServMattBegntime());
            //办件对象类型
            //TODO 字段
            servMattInstCDOObj.put("affairTargetType", "个人");
            //办件对象名字
            servMattInstCDOObj.put("affairTargetName", ser.getPtcpName());
            //办件对象证件
            servMattInstCDOObj.put("affairTargetNo", ser.getPtcp());
            //评审人姓名
            servMattInstCDOObj.put("userName", exField.getAgnterName());
            //评审人类型，类型只有个人。
            servMattInstCDOObj.put("userType", "个人(居民业务)");
            //评审人证件类型，分为身份证与其他有效证件。
            //TODO 存的是数字还是文字
            servMattInstCDOObj.put("certificateType", exField.getAgnterCertType());
//            if (StringUtils.equals("111", exField.getAgnterCertType())) {
//                servMattInstCDOObj.put("certificateType", "身份证");
//            } else {
//                servMattInstCDOObj.put("certificateType", "其他有效证件");
//            }
            //评审人证件号
            servMattInstCDOObj.put("certificateNo", exField.getAgnterCertNo());
            //评审人手机号
            servMattInstCDOObj.put("contactPhone", exField.getAgnterTel());
        }
        //政府网UserId
        servMattInstCDOObj.put("zwwUserId", exField.getUserId());
        //办件对象证件类型
        //TODO 存文字还是数字
        servMattInstCDOObj.put("affairTargetNoType", ser.getPtcpType());
//        if (StringUtils.equals("111", ser.getPtcpType())) {
//            servMattInstCDOObj.put("affairTargetNoType", "身份证");
//        }
//        if (StringUtils.equals("001", ser.getPtcpType())) {
//            servMattInstCDOObj.put("affairTargetNoType", "统一社会信用代码");
//        }
        return servMattInstCDOObj;
    }

    /**
     * post请求传递json数据获取json数据。
     *
     * @param jsonArray json对象数组
     * @return
     */
    public void sendPostRequest(JSONObject jsonArray) {
        //测试环境发送请求。
        String url = "http://10.255.40.119/dlybjcep/rae/web/transData/addAffairEval";
        //        请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("user-agent", "Mozilla/5.0 WindSnowLi-Blog");
        //        整合请求头和请求参数
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(jsonArray, headers);
        //         请求客户端
        RestTemplate client = new RestTemplate();
        //      发起请求
        JSONObject body = client.postForEntity(url, httpEntity, JSONObject.class).getBody();
        System.out.println("******** POST请求 *********");
        assert body != null;
        System.out.println(body.toJSONString());
    }

    /**
     * 事务名称匹配事务编号,组装办件编号。
     * 组装逻辑：实例ID+自定义编号。
     *
     * @param servMattName,servMattInstID,map
     */
    private void matchServMattNo(String servMattName, String servMattInstID, Map<String, Object> map) {
        String affairSerialNo = "";
        String affairCode = "";
        if (StringUtils.isNotBlank(servMattName)) {
            switch (servMattName) {
                case "城乡居民参保登记":
                    //"01"为自定义编号。
                    affairSerialNo = servMattInstID + "01";
                    affairCode = "11210200MB1646401N3212000382014";
                    break;
                case "城乡居民参保信息变更登记":
                    affairSerialNo = servMattInstID + "02";
                    affairCode = "11210200MB1646401N3212000382017";
                    break;
                case "产前检查费支付":
                    affairSerialNo = servMattInstID + "03";
                    affairCode = "11210200MB1646401N3212000807001";
                    break;
                case "计划生育医疗费支付":
                    affairSerialNo = servMattInstID + "04";
                    affairCode = "11210200MB1646401N3212000807003";
                    break;
                case "生育津贴支付":
                    affairSerialNo = servMattInstID + "05";
                    affairCode = "11210200MB1646401N3212000807003";
                    break;
                case "生育医疗费支付":
                    affairSerialNo = servMattInstID + "06";
                    affairCode = "11210200MB1646401N3212000807002";
                    break;
                case "参保人员个人账户一次性支取":
                    affairSerialNo = servMattInstID + "07";
                    affairCode = "11210200MB1646401N3212000781003";
                    break;
                case "零售药店申请定点协议管理":
                    affairSerialNo = servMattInstID + "08";
                    affairCode = "11210200MB1646401N3212000809002";
                    break;
                case "医疗机构申请定点协议管理":
                    affairSerialNo = servMattInstID + "09";
                    affairCode = "11210200MB1646401N3212000809001";
                    break;
                case "基本医疗保险参保人员享受门诊慢特病病种待遇认定":
                    affairSerialNo = servMattInstID + "10";
                    affairCode = "11210200MB1646401N3212000806000";
                    break;
                case "转移接续手续办理":
                    affairSerialNo = servMattInstID + "11";
                    affairCode = "11210200MB1646401N3212000803002";
                    break;
                case "常驻异地工作人员备案":
                    affairSerialNo = servMattInstID + "12";
                    affairCode = "11210200MB1646401N3212000804003";
                    break;
                case "异地长期居住人员备案":
                    affairSerialNo = servMattInstID + "13";
                    affairCode = "11210200MB1646401N3212000804002";
                    break;
                case "异地转诊人员备案":
                    affairSerialNo = servMattInstID + "14";
                    affairCode = "11210200MB1646401N3212000804004";
                    break;
                case "异地安置退休人员备案":
                    affairSerialNo = servMattInstID + "15";
                    affairCode = "11210200MB1646401N3212000804001";
                    break;
                case "医疗救助对象手工（零星）报销":
                    affairSerialNo = servMattInstID + "16";
                    affairCode = "11210200MB1646401N3212000808002";
                    break;
                case "符合资助条件的救助对象参加城乡居民基本医疗保险个人缴费补贴":
                    affairSerialNo = servMattInstID + "17";
                    affairCode = "11210200MB1646401N3212000808001";
                    break;
                default:
                    break;
            }
        }
        map.put("affairSerialNo", affairSerialNo);
        map.put("affairCode", affairCode);
    }

    /**
     * mysql渠道标识转换
     *
     * @param flag
     */
    private String matchChnlFlag(String flag) {
        String cka292 = "";
        if (StringUtils.isNotBlank(flag)) {
            switch (flag) {
                case "002":
                    cka292 = "APP";
                    break;
                case "003":
                    cka292 = "微信公众号";
                    break;
                case "004":
                    cka292 = "个人网厅";
                    break;
                case "005":
                    cka292 = "单位网厅";
                    break;
                case "006":
                    cka292 = "支付宝生活号";
                    break;
                case "007":
                    cka292 = "政务平台";
                    break;
                case "008":
                    cka292 = "电子凭证";
                    break;
                case "009":
                    cka292 = "省政务平台（单位网厅）";
                    break;
                case "011":
                    cka292 = "市民云";
                    break;
                case "012":
                    cka292 = "辽事通";
                    break;
                case "013":
                    cka292 = "医保执法";
                    break;
                case "014":
                    cka292 = "招行";
                    break;
                case "015":
                    cka292 = "农行";
                    break;
                case "016":
                    cka292 = "公安";
                    break;
                case "017":
                    cka292 = "交行";
                    break;
            }
        }
        return cka292;
    }
}

